package org.datascooter.inface;

import java.util.Collection;
import java.util.List;

import org.datascooter.bundle.ContainerProvider;
import org.datascooter.bundle.attribute.PersistAttribute;
import org.datascooter.exception.EntityNotMappedException;
import org.datascooter.impl.DataSnip;
import org.datascooter.impl.Snip;
import org.datascooter.meta.Column;
import org.datascooter.meta.MetaColumn;
import org.datascooter.meta.MetaLink;
import org.datascooter.utils.DBType;
import org.datascooter.utils.policy.SnipType;

/**
 * Builds a Snip from DataSnip - the main task before executing methods of a SnipManager
 * 
 * @author nemo
 * 
 */
public interface ISnipBuilder {

	/**
	 * Copies a builder for many independent session
	 * 
	 * @return ISnipBuilder
	 */
	public ISnipBuilder copy();

	/**
	 * Builds a Snip from DataSnip use entityMapper
	 * 
	 * @param dataSnip
	 * @return Snip
	 * @throws EntityNotMappedException
	 * @throws NoSuchMethodException
	 * @throws SecurityException
	 * @throws BuildClauseException
	 */
	public Snip build(DataSnip dataSnip, String transactionId) throws EntityNotMappedException, SecurityException, NoSuchMethodException;

	/**
	 * Builds a snip for update column
	 * 
	 * @param entity
	 * @param attribute
	 * @return Snip
	 * @throws EntityNotMappedException
	 * @throws NoSuchMethodException
	 * @throws SecurityException
	 */
	public Snip buildUpdateColumnSnip(String entity, PersistAttribute attribute) throws EntityNotMappedException, SecurityException, NoSuchMethodException;

	/**
	 * Builds a snip for create column
	 * 
	 * @param entity
	 * @param attribute
	 * @return Snip
	 * @throws EntityNotMappedException
	 * @throws NoSuchMethodException
	 * @throws SecurityException
	 */
	public Snip buildCreateColumnSnip(String entity, PersistAttribute attribute) throws EntityNotMappedException, SecurityException, NoSuchMethodException;

	/**
	 * Equals a type of column received from database metadata with datascooter mappings - should be overridden for each database
	 * 
	 * @param attribute
	 * @param column
	 * @return boolean
	 */
	public boolean equalType(PersistAttribute attribute, Column column);

	/**
	 * Returns a database type
	 * 
	 * @return String
	 */
	public String getContextId();

	/**
	 * Builds a table name in right case depend of a database
	 * 
	 * @param bundle
	 * @return String
	 */
	public String getCaseSensitiveTableName(String tableName);

	public String managePage(DataSnip dataSnip, String sqlClause);

	public void managePageParams(DataSnip dataSnip, List<Object> paramList);

	public Snip saveSnipInt(Snip snip, String transactionId) throws EntityNotMappedException, SecurityException, NoSuchMethodException;

	public Snip updateSnipInt(Snip snip, String transactionId) throws EntityNotMappedException, SecurityException, NoSuchMethodException;

	public Snip deleteSnipInt(Snip snip, String transactionId) throws EntityNotMappedException, SecurityException, NoSuchMethodException;

	public <T> Snip getCollectionSnip(Collection<?> input, SnipType insert, String transactionId, IDataManager dataManager) throws EntityNotMappedException;

	public Snip buildCreateSnip(DataSnip dataSnip) throws EntityNotMappedException, SecurityException, NoSuchMethodException;

	public Snip[] buildFetch(DataSnip dataSnip, String transactionId) throws EntityNotMappedException, SecurityException, NoSuchMethodException;

	public DataSnip createEmptyEntitySnip(String entity) throws EntityNotMappedException, SecurityException, NoSuchMethodException;

	public void init(DataSnip dataSnip) throws EntityNotMappedException, SecurityException, NoSuchMethodException;

	public String buildSelect(DataSnip dataSnip) throws EntityNotMappedException;

	public Object[][] customParamTypes(List<?> paramList);

	public String getDbTypeString(DBType type);

	public String buildMetaColumnClause(MetaColumn column);

	public void buildPrimaryIndex(DataSnip dataSnip);

	public void setContainerProvider(ContainerProvider crossProvider);

	public String dropKey(MetaLink link);

	public String buildColumnClause(PersistAttribute attribute);

	public Snip buildUpdateColumnSnip(String entity, String columName, String typeName, int scale, int precision, boolean nullable);
}
